package cn.clj1.builtInFunctions;

import cn.clj1.MyClojureInterp;
import cn.clj1.cell.CljCell;
import cn.clj1.cell.CljCellType;
import cn.clj1.recur.CljRecur;

import java.util.Date;
import java.util.Hashtable;
import java.util.List;

public class Cljlogic {
    /**
     * cond 计算
     * */
    public static CljCell Clj_list_cond(List<CljCell> lst, Hashtable<String, CljCell> funcHs, CljRecur cljRecur, CljCell rs) throws Exception {
        // cond 计算
        if (lst.size() > 1 && lst.size() % 2 > 0) {
            for (int i = 1; i < lst.size(); i += 2) {
                if (lst.size() > i + 1) {
                    CljCell c = lst.get(i);
                    if (c.getCljCellType() == CljCellType.Clj_list) {
                        CljCell rs1 = MyClojureInterp.eval(c, funcHs, cljRecur, rs);
                        if (rs1 != null && rs1.getCljCellType() == CljCellType.boolean_clj && (boolean)rs1.getCell())
                        {
                            return MyClojureInterp.eval(lst.get(i + 1), funcHs, cljRecur, rs1);
                        }
                    } else if (c.getCljCellType() == CljCellType.boolean_clj){
                        return MyClojureInterp.eval(lst.get(i + 1), funcHs, cljRecur, rs);
                    } else {
                        throw new Exception("unexpected (cond " + lst.get(i).toString() + ") 这里面的数据必须成对！");
                    }
                }
                else {
                    throw new Exception("unexpected (cond " + lst.get(i).toString() + ") 这里面的数据必须成对！");
                }
            }
        }
        return null;
    }

    /**
     * if 计算
     * */
    public static CljCell Clj_list_if(List<CljCell> lst, Hashtable<String, CljCell> funcHs, CljRecur cljRecur,CljCell rs) throws Exception {
        // if 计算
        if (lst.size() == 3) {
            CljCell c = lst.get(1);
            if (c.getCljCellType() == CljCellType.Clj_list) {
                CljCell rs1 = MyClojureInterp.eval(c, funcHs, cljRecur, rs);
                if (rs1 != null && rs1.getCljCellType() == CljCellType.boolean_clj && (boolean)rs1.getCell())
                {
                    return MyClojureInterp.eval(lst.get(2), funcHs, cljRecur, rs);
                }
            } else if (c.getCljCellType() == CljCellType.boolean_clj && (boolean)c.getCell()){
                return MyClojureInterp.eval(lst.get(2), funcHs, cljRecur, rs);
            }
        } else if (lst.size() == 4) {
            CljCell c = lst.get(1);
            if (c.getCljCellType() == CljCellType.Clj_list) {
                CljCell rs1 = MyClojureInterp.eval(c, funcHs, cljRecur, rs);
                if (rs1 != null && rs1.getCljCellType() == CljCellType.boolean_clj && (boolean)rs1.getCell())
                {
                    return MyClojureInterp.eval(lst.get(2), funcHs, cljRecur, rs);
                } else {
                    return MyClojureInterp.eval(lst.get(3), funcHs, cljRecur, rs);
                }
            } else if (c.getCljCellType() == CljCellType.boolean_clj){
                if ((boolean)c.getCell()) {
                    return MyClojureInterp.eval(lst.get(2), funcHs, cljRecur, rs);
                } else {
                    return MyClojureInterp.eval(lst.get(3), funcHs, cljRecur, rs);
                }
            }
        }
        return null;
    }

    /**
     * and
     * */
    public static CljCell Clj_list_and(List<CljCell> lst, Hashtable<String, CljCell> funcHs, CljRecur cljRecur,CljCell rs) throws Exception {
        /**
         * (and () ())
         * */
        boolean myrs = true;
        if (lst.size() > 1) {
            for (int i = 1; i < lst.size(); i++) {
                CljCell c = lst.get(i);
                if (c.getCljCellType() == CljCellType.boolean_clj && (boolean)c.getCell() == false) {
                    rs.setCljCellType(CljCellType.boolean_clj);
                    rs.setCell(false);
                    return rs;
                }
                else if (c.getCljCellType() == CljCellType.Clj_list) {
                    CljCell rs1 = MyClojureInterp.eval((CljCell) c.getCell(), funcHs, cljRecur, rs);
                    if (rs1 != null && rs.getCljCellType() == CljCellType.boolean_clj && (boolean)rs1.getCell() == false)
                    {
                        rs1.setCljCellType(CljCellType.boolean_clj);
                        rs1.setCell(false);
                        return rs1;
                    }
                    else {
                        throw new Exception("unexpected " + c.getCell().toString() + "的结果是非 boolean 类型！");
                    }
                }
            }
        }
        rs.setCljCellType(CljCellType.boolean_clj);
        rs.setCell(myrs);
        return rs;
    }

    /**
     * or
     * */
    public static CljCell Clj_list_or(List<CljCell> lst, Hashtable<String, CljCell> funcHs, CljRecur cljRecur,CljCell rs) throws Exception {
        /**
         * (or () ())
         * */
        boolean myrs = false;
        if (lst.size() > 1) {
            for (int i = 1; i < lst.size(); i++) {
                CljCell c = lst.get(i);
                if (c.getCljCellType() == CljCellType.boolean_clj && (boolean) c.getCell() == true) {
                    myrs = true;
                    break;
                } else if (c.getCljCellType() == CljCellType.Clj_list) {
                    CljCell rs1 = MyClojureInterp.eval((CljCell) c.getCell(), funcHs, cljRecur, rs);
                    if (rs1 != null && rs1.getCljCellType() == CljCellType.boolean_clj && (boolean) rs1.getCell() == true) {
                        myrs = true;
                        break;
                    } else {
                        throw new Exception("unexpected " + c.getCell().toString() + "的结果是非 boolean 类型！");
                    }
                }
            }
        }
        rs.setCljCellType(CljCellType.boolean_clj);
        rs.setCell(myrs);
        return rs;
    }

    /**
     * 等于
     * */
    public static CljCell Clj_list_equals(List<CljCell> lst, Hashtable<String, CljCell> funcHs, CljRecur cljRecur,CljCell rs) throws Exception {
        boolean myrs = true;
        if (lst.size() > 1) {
            CljCell tmp = lst.get(1);
            for (int i = 2; i < lst.size(); i++) {
                CljCell c = lst.get(i);
                if (c.getCljCellType() == CljCellType.number_clj && !c.getCell().equals(tmp.getCell())) {
                    myrs = false;
                    break;
                } else if (c.getCljCellType() == CljCellType.Clj_list) {

                    CljCell rs1 = MyClojureInterp.eval((CljCell) c.getCell(), funcHs, cljRecur, rs);
                    if (rs1.getCljCellType() == CljCellType.boolean_clj && !rs1.getCell().equals(tmp.getCell())) {
                        myrs = false;
                        break;
                    } else {
                        throw new Exception("unexpected " + c.getCell().toString() + "的结果是非 boolean 类型！");
                    }
                }
            }
        }
        rs.setCljCellType(CljCellType.boolean_clj);
        rs.setCell(myrs);
        return rs;
    }

    /**
     * 大于 只有数值类型、日期类型才能比大小
     * */
    public static CljCell Clj_list_greater_than(List<CljCell> lst, Hashtable<String, CljCell> funcHs, CljRecur cljRecur,CljCell rs) throws Exception {
        boolean myrs = true;
        if (lst.size() > 1) {
            CljCell tmp = lst.get(1);
            for (int i = 2; i < lst.size(); i++) {
                CljCell c = lst.get(i);
                // c 数值类型
                if (c.getCljCellType() == CljCellType.number_clj) {
                    if (tmp.getCljCellType() == CljCellType.number_clj) {
                        Number n1 = (Number)tmp.getCell();
                        Number n2 = (Number)c.getCell();
                        if (n1.doubleValue() <= n2.doubleValue()) {
                            myrs = false;
                            break;
                        }
                        tmp = lst.get(i);
                    } else if ((tmp.getCljCellType() == CljCellType.symbol || tmp.getCljCellType() == CljCellType.percent) && funcHs != null) {
                        CljCell cljCell = funcHs.get(tmp.getCell().toString());
                        if (cljCell != null && cljCell.getCljCellType() == CljCellType.number_clj) {
                            Number n1 = (Number)cljCell.getCell();
                            Number n2 = (Number)c.getCell();
                            if (n1.doubleValue() <= n2.doubleValue()) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        } else {
                            throw new Exception("unexpected " + tmp.getCell().toString() + " 非数值类型不能比较！");
                        }
                    } else if (tmp.getCljCellType() == CljCellType.Clj_list)  {
                        CljCell rs1 = MyClojureInterp.eval(tmp, funcHs, cljRecur, rs);
                        if (rs1 != null && rs1.getCljCellType() == CljCellType.number_clj) {
                            Number n1 = (Number) rs1.getCell();
                            Number n2 = (Number) c.getCell();
                            if (n1.doubleValue() <= n2.doubleValue()) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        }
                    } else {
                        throw new Exception("unexpected " + tmp.getCell().toString() + " 非数值类型不能比较！");
                    }
                }
                // date 类型
                else if (c.getCljCellType() == CljCellType.date_clj) {
                    if (tmp.getCljCellType() == CljCellType.date_clj) {
                        Date n1 = (Date)tmp.getCell();
                        Date n2 = (Date)c.getCell();
                        int comparison = n1.compareTo(n2);
                        if (comparison <= 0) {
                            myrs = false;
                            break;
                        }
                        tmp = lst.get(i);
                    } else if ((tmp.getCljCellType() == CljCellType.symbol || tmp.getCljCellType() == CljCellType.percent) && funcHs != null) {
                        CljCell cljCell = funcHs.get(tmp.getCell().toString());
                        if (cljCell != null && cljCell.getCljCellType() == CljCellType.date_clj) {
                            Date n1 = (Date)cljCell.getCell();
                            Date n2 = (Date)c.getCell();
                            int comparison1 = n1.compareTo(n2);
                            if (comparison1 <= 0) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        }  else {
                            throw new Exception("unexpected " + tmp.getCell().toString() + " 非数值类型不能比较！");
                        }
                    } else if (tmp.getCljCellType() == CljCellType.Clj_list) {
                        CljCell rs1 = MyClojureInterp.eval(tmp, funcHs, cljRecur, rs);
                        if (rs1 != null && rs1.getCljCellType() == CljCellType.date_clj) {
                            Date n1 = (Date) rs1.getCell();
                            Date n2 = (Date) c.getCell();
                            int comparison2 = n1.compareTo(n2);
                            if (comparison2 <= 0) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        }
                    } else {
                        throw new Exception("unexpected " + tmp.getCell().toString() + " 非数值类型不能比较！");
                    }
                }
                // Clj_list 类型
                else if (c.getCljCellType() == CljCellType.Clj_list) {
                    CljCell rs1 = MyClojureInterp.eval(c, funcHs, cljRecur, rs);
                    if (rs1 != null && tmp.getCljCellType() == CljCellType.number_clj && rs1.getCljCellType() == CljCellType.number_clj) {
                        Number n1 = (Number)tmp.getCell();
                        Number n2 = (Number)rs1.getCell();
                        if (n1.doubleValue() <= n2.doubleValue()) {
                            myrs = false;
                            break;
                        }
                        tmp = lst.get(i);
                    } else if (rs1 != null && tmp.getCljCellType() == CljCellType.date_clj && rs1.getCljCellType() == CljCellType.date_clj) {
                        Date n1 = (Date)tmp.getCell();
                        Date n2 = (Date)rs1.getCell();
                        int comparison = n1.compareTo(n2);
                        if (comparison <= 0) {
                            myrs = false;
                            break;
                        }
                        tmp = lst.get(i);
                    } else if (rs1 != null && (tmp.getCljCellType() == CljCellType.symbol || tmp.getCljCellType() == CljCellType.percent) && funcHs != null) {
                        CljCell cljCell = funcHs.get(tmp.getCell().toString());
                        if (cljCell != null && cljCell.getCljCellType() == CljCellType.date_clj && rs1.getCljCellType() == CljCellType.date_clj) {
                            Date n1 = (Date)cljCell.getCell();
                            Date n2 = (Date)rs1.getCell();
                            int comparison1 = n1.compareTo(n2);
                            if (comparison1 <= 0) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        } else if (cljCell != null && cljCell.getCljCellType() == CljCellType.number_clj && rs1.getCljCellType() == CljCellType.number_clj) {
                            Number n1 = (Number)tmp.getCell();
                            Number n2 = (Number)rs1.getCell();
                            if (n1.doubleValue() <= n2.doubleValue()) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        } else {
                            throw new Exception("unexpected " + c.getCell().toString() + " 非数值类型或者日期类型不能比较！");
                        }
                    }
                }
            }
            rs.setCljCellType(CljCellType.boolean_clj);
            rs.setCell(myrs);
            return rs;
        }
        return null;
    }

    /**
     * 小于
     * */
    public static CljCell Clj_list_less_than(List<CljCell> lst, Hashtable<String, CljCell> funcHs, CljRecur cljRecur,CljCell rs) throws Exception {
        boolean myrs = true;
        if (lst.size() > 1) {
            CljCell tmp = lst.get(1);
            for (int i = 2; i < lst.size(); i++) {
                CljCell c = lst.get(i);
                // c 数值类型
                if (c.getCljCellType() == CljCellType.number_clj) {
                    if (tmp.getCljCellType() == CljCellType.number_clj) {
                        Number n1 = (Number)tmp.getCell();
                        Number n2 = (Number)c.getCell();
                        if (n1.doubleValue() >= n2.doubleValue()) {
                            myrs = false;
                            break;
                        }
                        tmp = lst.get(i);
                    } else if ((tmp.getCljCellType() == CljCellType.symbol || tmp.getCljCellType() == CljCellType.percent) && funcHs != null) {
                        CljCell cljCell = funcHs.get(tmp.getCell().toString());
                        if (cljCell != null && cljCell.getCljCellType() == CljCellType.number_clj) {
                            Number n1 = (Number)cljCell.getCell();
                            Number n2 = (Number)c.getCell();
                            if (n1.doubleValue() >= n2.doubleValue()) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        } else {
                            throw new Exception("unexpected " + tmp.getCell().toString() + " 非数值类型不能比较！");
                        }
                    } else if (tmp.getCljCellType() == CljCellType.Clj_list)  {
                        CljCell rs1 = MyClojureInterp.eval(tmp, funcHs, cljRecur, rs);
                        if (rs1 != null && rs1.getCljCellType() == CljCellType.number_clj) {
                            Number n1 = (Number) rs1.getCell();
                            Number n2 = (Number) c.getCell();
                            if (n1.doubleValue() >= n2.doubleValue()) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        }
                    } else {
                        throw new Exception("unexpected " + tmp.getCell().toString() + " 非数值类型不能比较！");
                    }
                }
                // date 类型
                else if (c.getCljCellType() == CljCellType.date_clj) {
                    if (tmp.getCljCellType() == CljCellType.date_clj) {
                        Date n1 = (Date)tmp.getCell();
                        Date n2 = (Date)c.getCell();
                        int comparison = n1.compareTo(n2);
                        if (comparison >= 0) {
                            myrs = false;
                            break;
                        }
                        tmp = lst.get(i);
                    } else if ((tmp.getCljCellType() == CljCellType.symbol || tmp.getCljCellType() == CljCellType.percent) && funcHs != null) {
                        CljCell cljCell = funcHs.get(tmp.getCell().toString());
                        if (cljCell != null && cljCell.getCljCellType() == CljCellType.date_clj) {
                            Date n1 = (Date)cljCell.getCell();
                            Date n2 = (Date)c.getCell();
                            int comparison1 = n1.compareTo(n2);
                            if (comparison1 >= 0) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        }  else {
                            throw new Exception("unexpected " + tmp.getCell().toString() + " 非数值类型不能比较！");
                        }
                    } else if (tmp.getCljCellType() == CljCellType.Clj_list) {
                        CljCell rs1 = MyClojureInterp.eval(tmp, funcHs, cljRecur, rs);
                        if (rs1 != null && rs1.getCljCellType() == CljCellType.date_clj) {
                            Date n1 = (Date) rs1.getCell();
                            Date n2 = (Date) c.getCell();
                            int comparison2 = n1.compareTo(n2);
                            if (comparison2 >= 0) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        }
                    } else {
                        throw new Exception("unexpected " + tmp.getCell().toString() + " 非数值类型不能比较！");
                    }
                }
                // Clj_list 类型
                else if (c.getCljCellType() == CljCellType.Clj_list) {
                    CljCell rs1 = MyClojureInterp.eval(c, funcHs, cljRecur, rs);
                    if (rs1 != null && tmp.getCljCellType() == CljCellType.number_clj && rs1.getCljCellType() == CljCellType.number_clj) {
                        Number n1 = (Number)tmp.getCell();
                        Number n2 = (Number)rs1.getCell();
                        if (n1.doubleValue() >= n2.doubleValue()) {
                            myrs = false;
                            break;
                        }
                        tmp = lst.get(i);
                    } else if (rs1 != null && tmp.getCljCellType() == CljCellType.date_clj && rs1.getCljCellType() == CljCellType.date_clj) {
                        Date n1 = (Date)tmp.getCell();
                        Date n2 = (Date)rs1.getCell();
                        int comparison = n1.compareTo(n2);
                        if (comparison >= 0) {
                            myrs = false;
                            break;
                        }
                        tmp = lst.get(i);
                    } else if (rs1 != null && (tmp.getCljCellType() == CljCellType.symbol || tmp.getCljCellType() == CljCellType.percent) && funcHs != null) {
                        CljCell cljCell = funcHs.get(tmp.getCell().toString());
                        if (cljCell != null && cljCell.getCljCellType() == CljCellType.date_clj && rs1.getCljCellType() == CljCellType.date_clj) {
                            Date n1 = (Date)cljCell.getCell();
                            Date n2 = (Date)rs1.getCell();
                            int comparison1 = n1.compareTo(n2);
                            if (comparison1 >= 0) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        } else if (cljCell != null && cljCell.getCljCellType() == CljCellType.number_clj && rs1.getCljCellType() == CljCellType.number_clj) {
                            Number n1 = (Number)tmp.getCell();
                            Number n2 = (Number)rs1.getCell();
                            if (n1.doubleValue() >= n2.doubleValue()) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        } else {
                            throw new Exception("unexpected " + c.getCell().toString() + " 非数值类型或者日期类型不能比较！");
                        }
                    }
                }
            }
            rs.setCljCellType(CljCellType.boolean_clj);
            rs.setCell(myrs);
            return rs;
        }
        return null;
    }

    /**
     * 大于等于
     * */
    public static CljCell Clj_list_greater_equals(List<CljCell> lst, Hashtable<String, CljCell> funcHs, CljRecur cljRecur,CljCell rs) throws Exception {
        boolean myrs = true;
        if (lst.size() > 1) {
            CljCell tmp = lst.get(1);
            for (int i = 2; i < lst.size(); i++) {
                CljCell c = lst.get(i);
                // c 数值类型
                if (c.getCljCellType() == CljCellType.number_clj) {
                    if (tmp.getCljCellType() == CljCellType.number_clj) {
                        Number n1 = (Number)tmp.getCell();
                        Number n2 = (Number)c.getCell();
                        if (n1.doubleValue() < n2.doubleValue()) {
                            myrs = false;
                            break;
                        }
                        tmp = lst.get(i);
                    } else if ((tmp.getCljCellType() == CljCellType.symbol || tmp.getCljCellType() == CljCellType.percent) && funcHs != null) {
                        CljCell cljCell = funcHs.get(tmp.getCell().toString());
                        if (cljCell != null && cljCell.getCljCellType() == CljCellType.number_clj) {
                            Number n1 = (Number)cljCell.getCell();
                            Number n2 = (Number)c.getCell();
                            if (n1.doubleValue() < n2.doubleValue()) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        } else {
                            throw new Exception("unexpected " + tmp.getCell().toString() + " 非数值类型不能比较！");
                        }
                    } else if (tmp.getCljCellType() == CljCellType.Clj_list)  {
                        CljCell rs1 = MyClojureInterp.eval(tmp, funcHs, cljRecur, rs);
                        if (rs1 != null && rs1.getCljCellType() == CljCellType.number_clj) {
                            Number n1 = (Number) rs1.getCell();
                            Number n2 = (Number) c.getCell();
                            if (n1.doubleValue() < n2.doubleValue()) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        }
                    } else {
                        throw new Exception("unexpected " + tmp.getCell().toString() + " 非数值类型不能比较！");
                    }
                }
                // date 类型
                else if (c.getCljCellType() == CljCellType.date_clj) {
                    if (tmp.getCljCellType() == CljCellType.date_clj) {
                        Date n1 = (Date)tmp.getCell();
                        Date n2 = (Date)c.getCell();
                        int comparison = n1.compareTo(n2);
                        if (comparison < 0) {
                            myrs = false;
                            break;
                        }
                        tmp = lst.get(i);
                    } else if ((tmp.getCljCellType() == CljCellType.symbol || tmp.getCljCellType() == CljCellType.percent) && funcHs != null) {
                        CljCell cljCell = funcHs.get(tmp.getCell().toString());
                        if (cljCell != null && cljCell.getCljCellType() == CljCellType.date_clj) {
                            Date n1 = (Date)cljCell.getCell();
                            Date n2 = (Date)c.getCell();
                            int comparison1 = n1.compareTo(n2);
                            if (comparison1 < 0) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        }  else {
                            throw new Exception("unexpected " + tmp.getCell().toString() + " 非数值类型不能比较！");
                        }
                    } else if (tmp.getCljCellType() == CljCellType.Clj_list) {
                        CljCell rs1 = MyClojureInterp.eval(tmp, funcHs, cljRecur, rs);
                        if (rs1 != null && rs1.getCljCellType() == CljCellType.date_clj) {
                            Date n1 = (Date) rs1.getCell();
                            Date n2 = (Date) c.getCell();
                            int comparison2 = n1.compareTo(n2);
                            if (comparison2 < 0) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        }
                    } else {
                        throw new Exception("unexpected " + tmp.getCell().toString() + " 非数值类型不能比较！");
                    }
                }
                // Clj_list 类型
                else if (c.getCljCellType() == CljCellType.Clj_list) {
                    CljCell rs1 = MyClojureInterp.eval(c, funcHs, cljRecur, rs);
                    if (rs1 != null && tmp.getCljCellType() == CljCellType.number_clj && rs1.getCljCellType() == CljCellType.number_clj) {
                        Number n1 = (Number)tmp.getCell();
                        Number n2 = (Number)rs1.getCell();
                        if (n1.doubleValue() < n2.doubleValue()) {
                            myrs = false;
                            break;
                        }
                        tmp = lst.get(i);
                    } else if (rs1 != null && tmp.getCljCellType() == CljCellType.date_clj && rs1.getCljCellType() == CljCellType.date_clj) {
                        Date n1 = (Date)tmp.getCell();
                        Date n2 = (Date)rs1.getCell();
                        int comparison = n1.compareTo(n2);
                        if (comparison < 0) {
                            myrs = false;
                            break;
                        }
                        tmp = lst.get(i);
                    } else if (rs1 != null && (tmp.getCljCellType() == CljCellType.symbol || tmp.getCljCellType() == CljCellType.percent) && funcHs != null) {
                        CljCell cljCell = funcHs.get(tmp.getCell().toString());
                        if (cljCell != null && cljCell.getCljCellType() == CljCellType.date_clj && rs1.getCljCellType() == CljCellType.date_clj) {
                            Date n1 = (Date)cljCell.getCell();
                            Date n2 = (Date)rs1.getCell();
                            int comparison1 = n1.compareTo(n2);
                            if (comparison1 < 0) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        } else if (cljCell != null && cljCell.getCljCellType() == CljCellType.number_clj && rs1.getCljCellType() == CljCellType.number_clj) {
                            Number n1 = (Number)tmp.getCell();
                            Number n2 = (Number)rs1.getCell();
                            if (n1.doubleValue() < n2.doubleValue()) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        } else {
                            throw new Exception("unexpected " + c.getCell().toString() + " 非数值类型或者日期类型不能比较！");
                        }
                    }
                }
            }
            rs.setCljCellType(CljCellType.boolean_clj);
            rs.setCell(myrs);
            return rs;
        }
        return null;
    }

    /**
     * 小于等于
     * */
    public static CljCell Clj_list_less_equals(List<CljCell> lst, Hashtable<String, CljCell> funcHs, CljRecur cljRecur,CljCell rs) throws Exception {
        boolean myrs = true;
        if (lst.size() > 1) {
            CljCell tmp = lst.get(1);
            for (int i = 2; i < lst.size(); i++) {
                CljCell c = lst.get(i);
                // c 数值类型
                if (c.getCljCellType() == CljCellType.number_clj) {
                    if (tmp.getCljCellType() == CljCellType.number_clj) {
                        Number n1 = (Number)tmp.getCell();
                        Number n2 = (Number)c.getCell();
                        if (n1.doubleValue() > n2.doubleValue()) {
                            myrs = false;
                            break;
                        }
                        tmp = lst.get(i);
                    } else if ((tmp.getCljCellType() == CljCellType.symbol || tmp.getCljCellType() == CljCellType.percent) && funcHs != null) {
                        CljCell cljCell = funcHs.get(tmp.getCell().toString());
                        if (cljCell != null && cljCell.getCljCellType() == CljCellType.number_clj) {
                            Number n1 = (Number)cljCell.getCell();
                            Number n2 = (Number)c.getCell();
                            if (n1.doubleValue() > n2.doubleValue()) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        } else {
                            throw new Exception("unexpected " + tmp.getCell().toString() + " 非数值类型不能比较！");
                        }
                    } else if (tmp.getCljCellType() == CljCellType.Clj_list)  {
                        CljCell rs1 = MyClojureInterp.eval(tmp, funcHs, cljRecur, rs);
                        if (rs1 != null && rs1.getCljCellType() == CljCellType.number_clj) {
                            Number n1 = (Number) rs1.getCell();
                            Number n2 = (Number) c.getCell();
                            if (n1.doubleValue() > n2.doubleValue()) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        }
                    } else {
                        throw new Exception("unexpected " + tmp.getCell().toString() + " 非数值类型不能比较！");
                    }
                }
                // date 类型
                else if (c.getCljCellType() == CljCellType.date_clj) {
                    if (tmp.getCljCellType() == CljCellType.date_clj) {
                        Date n1 = (Date)tmp.getCell();
                        Date n2 = (Date)c.getCell();
                        int comparison = n1.compareTo(n2);
                        if (comparison > 0) {
                            myrs = false;
                            break;
                        }
                        tmp = lst.get(i);
                    } else if ((tmp.getCljCellType() == CljCellType.symbol || tmp.getCljCellType() == CljCellType.percent) && funcHs != null) {
                        CljCell cljCell = funcHs.get(tmp.getCell().toString());
                        if (cljCell != null && cljCell.getCljCellType() == CljCellType.date_clj) {
                            Date n1 = (Date)cljCell.getCell();
                            Date n2 = (Date)c.getCell();
                            int comparison1 = n1.compareTo(n2);
                            if (comparison1 > 0) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        }  else {
                            throw new Exception("unexpected " + tmp.getCell().toString() + " 非数值类型不能比较！");
                        }
                    } else if (tmp.getCljCellType() == CljCellType.Clj_list) {
                        CljCell rs1 = MyClojureInterp.eval(tmp, funcHs, cljRecur, rs);
                        if (rs1 != null && rs1.getCljCellType() == CljCellType.date_clj) {
                            Date n1 = (Date) rs1.getCell();
                            Date n2 = (Date) c.getCell();
                            int comparison2 = n1.compareTo(n2);
                            if (comparison2 > 0) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        }
                    } else {
                        throw new Exception("unexpected " + tmp.getCell().toString() + " 非数值类型不能比较！");
                    }
                }
                // Clj_list 类型
                else if (c.getCljCellType() == CljCellType.Clj_list) {
                    CljCell rs1 = MyClojureInterp.eval(c, funcHs, cljRecur, rs);
                    if (rs1 != null && tmp.getCljCellType() == CljCellType.number_clj && rs1.getCljCellType() == CljCellType.number_clj) {
                        Number n1 = (Number)tmp.getCell();
                        Number n2 = (Number)rs1.getCell();
                        if (n1.doubleValue() > n2.doubleValue()) {
                            myrs = false;
                            break;
                        }
                        tmp = lst.get(i);
                    } else if (rs1 != null && tmp.getCljCellType() == CljCellType.date_clj && rs1.getCljCellType() == CljCellType.date_clj) {
                        Date n1 = (Date)tmp.getCell();
                        Date n2 = (Date)rs1.getCell();
                        int comparison = n1.compareTo(n2);
                        if (comparison > 0) {
                            myrs = false;
                            break;
                        }
                        tmp = lst.get(i);
                    } else if (rs1 != null && (tmp.getCljCellType() == CljCellType.symbol || tmp.getCljCellType() == CljCellType.percent) && funcHs != null) {
                        CljCell cljCell = funcHs.get(tmp.getCell().toString());
                        if (cljCell != null && cljCell.getCljCellType() == CljCellType.date_clj && rs1.getCljCellType() == CljCellType.date_clj) {
                            Date n1 = (Date)cljCell.getCell();
                            Date n2 = (Date)rs1.getCell();
                            int comparison1 = n1.compareTo(n2);
                            if (comparison1 > 0) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        } else if (cljCell != null && cljCell.getCljCellType() == CljCellType.number_clj && rs1.getCljCellType() == CljCellType.number_clj) {
                            Number n1 = (Number)tmp.getCell();
                            Number n2 = (Number)rs1.getCell();
                            if (n1.doubleValue() > n2.doubleValue()) {
                                myrs = false;
                                break;
                            }
                            tmp = lst.get(i);
                        } else {
                            throw new Exception("unexpected " + c.getCell().toString() + " 非数值类型或者日期类型不能比较！");
                        }
                    }
                }
            }
            rs.setCljCellType(CljCellType.boolean_clj);
            rs.setCell(myrs);
            return rs;
        }
        return null;
    }

    /**
     * not 语句
     * */
    public static CljCell Clj_list_not(List<CljCell> lst, Hashtable<String, CljCell> funcHs, CljRecur cljRecur,CljCell rs) throws Exception {
        if (lst.size() == 2) {
            CljCell c = lst.get(1);
            if (c.getCljCellType() == CljCellType.boolean_clj) {
                boolean b = (boolean)c.getCell();
                rs.setCell(!b);
            } else {
                CljCell rs1 = MyClojureInterp.eval(c, funcHs, cljRecur, new CljCell());
                if (rs1 != null && rs1.getCljCellType() == CljCellType.boolean_clj) {
                    boolean b = (boolean)rs1.getCell();
                    rs1.setCell(!b);
                    return rs1;
                } else {
                    throw new Exception("(not x) 如果 x 为逻辑 false，则返回 true，否则返回 false。");
                }
            }
        } else {
            throw new Exception("(not x) 如果 x 为逻辑 false，则返回 true，否则返回 false。");
        }
        return null;
    }

    /**
     * nil? 语句
     * */
    public static CljCell Clj_list_is_nil(List<CljCell> lst, Hashtable<String, CljCell> funcHs, CljRecur cljRecur,CljCell rs) throws Exception {
        if (lst.size() == 2) {
            CljCell c = lst.get(1);
            if (c.getCljCellType() == CljCellType.nil) {
                rs.setCell(true);
                rs.setCljCellType(CljCellType.boolean_clj);
                return rs;
            } else {
                CljCell rs1 = MyClojureInterp.eval(c, funcHs, cljRecur, rs);
                if (rs1.getCljCellType() == CljCellType.nil) {
                    rs1.setCell(true);
                    rs1.setCljCellType(CljCellType.boolean_clj);
                } else {
                    rs1.setCell(false);
                    rs1.setCljCellType(CljCellType.boolean_clj);
                }
                return rs1;
            }
        } else {
            throw new Exception("使用建议：(nil? x) 如果 x 为 nil，则返回 true，否则返回 false。");
        }
    }

}


































